﻿using System;
using System.Collections.Generic;
using System.Web;

using JigsawService.Parsers;
using JigsawService.Utility;
using JigsawService.DataAccess.Security;

namespace JigsawService.Controllers
{
    public class SystemAdmin : JigsawBase
    {
        APIMessage _apimessage;

        public SystemAdmin(APIMessage apiMessage)
        {
            _apimessage = apiMessage;
        }

        /// <summary>
        /// The SystemAdmin controller should only be accessible to admin users
        /// </summary>
        public void Controller()
        {
            _apimessage.StateMessage = "SystemAdmin Controller: ";

            // method access authorization
            if (_apimessage.ValidateMethodAccess(_apimessage.APIString))
            {
                switch (_apimessage.APIString)
                {
                    // ****************************************
                    // Process
                    // ****************************************

                    case "SystemAdmin.UserLogin.Base":
                        UserLogin();
                        break;

                    case "SystemAdmin.UpdatePassword.Process":
                        UpdatePassword();
                        break;

                    case "SystemAdmin.UpdateAccess.Process":
                        UpdateAccess();
                        break;

                    case "SystemAdmin.NewUserAccount.Process":
                        NewUserAccount();
                        break;

                    // ****************************************
                    // Select
                    // ****************************************

                    case "SystemAdmin.GetLastNameLetters.Base":
                        GetLastNameLetters();
                        break;

                    case "SystemAdmin.GetLastInitialUsers.Base":
                        GetLastInitialUsers();
                        break;

                    case "SystemAdmin.GetUserVersions.Base":
                        GetUserVersions();
                        break;

                    case "SystemAdmin.GetUser.Base":
                        GetUser();
                        break;

                    case "SystemAdmin.GetAllAPIs.Base":
                        GetAllAPIs();
                        break;

                    case "SystemAdmin.GetAPIMethods.Base":
                        GetAPIMethods();
                        break;

                    case "SystemAdmin.GetMethodVersions.Base":
                        GetMethodVersions();
                        break;

                    case "SystemAdmin.GetAllRoles.Base":
                        GetAllRoles();
                        break;

                    case "SystemAdmin.GetRoleVersions.Base":
                        GetRoleVersions();
                        break;

                    case "SystemAdmin.GetAllGroups.Base":
                        GetAllGroups();
                        break;

                    case "SystemAdmin.GetGroupVersions.Base":
                        GetGroupVersions();
                        break;

                    // ****************************************
                    // Action
                    // ****************************************

                    case "SystemAdmin.NewUserAccount.Base":
                        UserAccountAction("Insert");
                        break;

                    case "SystemAdmin.SaveUserAccount.Base":
                        UserAccountAction("Update");
                        break;

                    case "SystemAdmin.DeleteUserAccount.Base":
                        UserAccountAction("Delete");
                        break;

                    case "SystemAdmin.NewMethod.Base":
                        MethodAction("Insert");
                        break;

                    case "SystemAdmin.SaveMethod.Base":
                        MethodAction("Update");
                        break;

                    case "SystemAdmin.DeleteMethod.Base":
                        MethodAction("Delete");
                        break;

                    case "SystemAdmin.NewAppRole.Base":
                        AppRoleAction("Insert");
                        break;

                    case "SystemAdmin.SaveAppRole.Base":
                        AppRoleAction("Update");
                        break;

                    case "SystemAdmin.DeleteAppRole.Base":
                        AppRoleAction("Delete");
                        break;

                    case "SystemAdmin.NewDataGroup.Base":
                        DataGroupAction("Insert");
                        break;

                    case "SystemAdmin.SaveDataGroup.Base":
                        DataGroupAction("Update");
                        break;

                    case "SystemAdmin.DeleteDataGroup.Base":
                        DataGroupAction("Delete");
                        break;
                }
            }
            else
            {
                throw new Exception("Method Authorization Failed for " + _apimessage.APIString);
            }
        }

        // ****************************************
        // ****************************************
        // ****************************************
        // ****************************************

        /// <summary>
        /// This method allows the user credentials to be authenticated and authorized, and if successful:
        /// a) returns the userID value, plus b) updates the UserAccount access summary fields.
        /// </summary>
        protected void UserLogin()
        {
            _apimessage.StateMessage = "SystemAdmin UserLogin: ";
            if (_apimessage.UserID != "")
            {
                // call method to update UserAccount access summary fields
                UserAccountDA uada = new UserAccountDA(_apimessage);
                uada.UpdateAccessSummary(_apimessage.UserID);

                SetSuccessResult(_apimessage.UserID, "text", _apimessage);
            }
            else
            {
                throw new Exception("Unable to retrieve UserID: " + _apimessage.APIString);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected void NewUserAccount()
        {
            _apimessage.StateMessage = "SystemAdmin NewUserAccount: ";

            // required
            string globalID = _apimessage.ValidateMethodParam("GlobalID");
            string userName = _apimessage.ValidateMethodParam("UserName");
            string passWord = _apimessage.ValidateMethodParam("Password");
            string firstName = _apimessage.ValidateMethodParam("FirstName");
            string lastName = _apimessage.ValidateMethodParam("LastName");
            string email = _apimessage.ValidateMethodParam("Email");
            string expiration = _apimessage.ValidateMethodParam("Expiration");

            if (globalID != "" && userName != "" && passWord != "" && firstName != "" && lastName != "" && email != "" && expiration != "")
            {
                UserAccountDA userda = new UserAccountDA(_apimessage);
                userda.NewUserAccount(globalID, userName, passWord, firstName, lastName, email, expiration);
            }
            else
            {
                throw new Exception("Missing required input parameter(s)");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected void UpdatePassword()
        {
            _apimessage.StateMessage = "SystemAdmin UpdatePassword: ";

            // required
            string userID = _apimessage.ValidateMethodParam("UserID");
            string userName = _apimessage.ValidateMethodParam("UserName");
            string password = _apimessage.ValidateMethodParam("Password");

            UserAccountDA userda = new UserAccountDA(_apimessage);
            userda.UpdatePassword(userID, userName, password);
        }

        /// <summary>
        /// 
        /// </summary>
        protected void UpdateAccess()
        {
            _apimessage.StateMessage = "SystemAdmin UpdateAccess: ";

            // required
            string userID = _apimessage.ValidateMethodParam("UserID");

            UserAccountDA userda = new UserAccountDA(_apimessage);
            userda.UpdateAccessSummary(userID);
        }

        // ****************************************
        // ****************************************

        /// <summary>
        /// returns a list of all distinct user lastname initials
        /// </summary>
        protected void GetLastNameLetters()
        {
            _apimessage.StateMessage = "SystemAdmin GetLastNameLetters: ";

            UserAccountDA userda = new UserAccountDA(_apimessage);
            userda.GetLastNameLetters();
        }

        /// <summary>
        /// 
        /// </summary>
        protected void GetLastInitialUsers()
        {
            _apimessage.StateMessage = "SystemAdmin GetLastInitialUsers: ";
            // required
            string lastNameInitial = _apimessage.ValidateMethodParam("Initial");

            UserAccountDA userda = new UserAccountDA(_apimessage);
            userda.GetLastInitialUsers(lastNameInitial);
        }

        /// <summary>
        /// 
        /// </summary>
        protected void GetUserVersions()
        {
            _apimessage.StateMessage = "SystemAdmin GetUserVersions: ";
            // required
            string userID = _apimessage.ValidateMethodParam("UserID");

            UserAccountDA userda = new UserAccountDA(_apimessage);
            userda.GetUserVersions(userID);
        }

        /// <summary>
        /// 
        /// </summary>
        protected void GetUser()
        {
            _apimessage.StateMessage = "SystemAdmin GetUser: ";
            // required
            string userID = _apimessage.ValidateMethodParam("UserID");

            UserAccountDA userda = new UserAccountDA(_apimessage);
            userda.GetUser(userID);
        }

        /// <summary>
        /// returns a list of all distinct APIName values
        /// </summary>
        protected void GetAllAPIs()
        {
            _apimessage.StateMessage = "SystemAdmin GetAllAPIs: ";

            MethodsDA methda = new MethodsDA(_apimessage);
            methda.GetAllAPIs();
        }

        /// <summary>
        /// 
        /// </summary>
        protected void GetAllRoles()
        {
            _apimessage.StateMessage = "SystemAdmin GetAllRoles: ";

            AppRoleDA arda = new AppRoleDA(_apimessage);
            arda.GetAllRoles();
        }

        /// <summary>
        /// 
        /// </summary>
        protected void GetRoleVersions()
        {
            _apimessage.StateMessage = "SystemAdmin GetRoleVersions: ";
            // required
            string roleID = _apimessage.ValidateMethodParam("RoleID");

            AppRoleDA arda = new AppRoleDA(_apimessage);
            arda.GetRoleVersions(roleID);
        }

        /// <summary>
        /// returns a list of all the methods for a given APIName
        /// </summary>
        protected void GetAPIMethods()
        {
            _apimessage.StateMessage = "SystemAdmin GetAPIMethods: ";
            // required
            string apiName = _apimessage.ValidateMethodParam("APIName");

            if (apiName != "")
            {
                MethodsDA methda = new MethodsDA(_apimessage);
                methda.GetAPIMethods(apiName);
            }
            else
            {
                throw new Exception("Missing required input parameter(s)");
            }
        }

        /// <summary>
        /// returns a list of all the versions (current and archived) for a given method
        /// </summary>
        protected void GetMethodVersions()
        {
            _apimessage.StateMessage = "SystemAdmin GetMethod: ";
            // required
            string methodID = _apimessage.ValidateMethodParam("MethodID");

            if (methodID != "")
            {
                MethodsDA methda = new MethodsDA(_apimessage);
                methda.GetMethodVersions(methodID);
            }
            else
            {
                throw new Exception("Missing required input parameter(s)");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected void GetAllGroups()
        {
            _apimessage.StateMessage = "SystemAdmin GetAllGroups: ";

            DataGroupDA dgda = new DataGroupDA(_apimessage);
            dgda.GetAllGroups();
        }

        /// <summary>
        /// 
        /// </summary>
        protected void GetGroupVersions()
        {
            _apimessage.StateMessage = "SystemAdmin GetGroupVersions: ";
            // required
            string groupID = _apimessage.ValidateMethodParam("GroupID");

            DataGroupDA dgda = new DataGroupDA(_apimessage);
            dgda.GetGroupVersions(groupID);
        }

        // ****************************************
        // ****************************************
        // ****************************************
        // ****************************************

        /// <summary>
        /// 
        /// </summary>
        protected void UserAccountAction(string actionType)
        {
            _apimessage.StateMessage = "SystemAdmin UserAccountAction: ";
            // required
            string globalID = _apimessage.ValidateMethodParam("GlobalID");
            string userName = _apimessage.ValidateMethodParam("UserName");
            string passWord = _apimessage.ValidateMethodParam("Password");
            string firstName = _apimessage.ValidateMethodParam("FirstName");
            string lastName = _apimessage.ValidateMethodParam("LastName");
            string email = _apimessage.ValidateMethodParam("Email");
            string expiration = _apimessage.ValidateMethodParam("Expiration");
            string methodaccesssummary = _apimessage.ValidateMethodParam("MethodAccessSummary");
            string dataaccesssummary = _apimessage.ValidateMethodParam("DataAccessSummary");
            
            // optional
            string methodAccessSummary = _apimessage.ValidateMethodParam("MethodAccessSummary");
            string dataAccessSummary = _apimessage.ValidateMethodParam("DataAcctssSummary");

            if (globalID != "" && userName != "" && passWord != "" && firstName != "" && lastName != "" && email != "" && expiration != "")
            {
                UserAccountDA userda = new UserAccountDA(_apimessage);
                userda.UserAccountAction(actionType, globalID, userName, passWord, firstName, lastName, email, expiration, methodaccesssummary, dataaccesssummary);
            }
            else
            {
                throw new Exception("Missing required input parameter(s)");
            }
        }

        /// <summary>
        /// The actionType value from the controller should not be confused with the atype input parameter;
        /// actionType determines whether an insert, update or delete will be performed, while the atype 
        /// input parameter describes the nature of the extenal API (controller) method being documented.
        /// </summary>
        protected void MethodAction(string actionType)
        {
            _apimessage.StateMessage = "SystemAdmin MethodAction: ";
            // required
            string globalID = _apimessage.ValidateMethodParam("GlobalID");
            string atype = _apimessage.ValidateMethodParam("ActionType");
            string apiName = _apimessage.ValidateMethodParam("APIName");
            string methodName = _apimessage.ValidateMethodParam("MethodName");
            string methodState = _apimessage.ValidateMethodParam("MethodState");

            if (globalID != "" && atype != "" && apiName != "" && methodName != "" && methodState != "")
            {
                MethodsDA methda = new MethodsDA(_apimessage);
                methda.MethodsAction(actionType, globalID, atype, apiName, methodName, methodState);
            }
            else
            {
                throw new Exception("Missing required input parameter(s)");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected void AppRoleAction(string actionType)
        {
            _apimessage.StateMessage = "SystemAdmin AppRoleAction: ";
            // required
            string globalID = _apimessage.ValidateMethodParam("GlobalID");
            string roleName = _apimessage.ValidateMethodParam("RoleName");
            // optional
            string description = _apimessage.ValidateMethodParam("Description");

            if (globalID != "" && roleName != "")
            {
                AppRoleDA roleda = new AppRoleDA(_apimessage);
                roleda.AppRoleAction(actionType, globalID, roleName, description);
            }
            else
            {
                throw new Exception("Missing required input parameter(s)");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected void DataGroupAction(string actionType)
        {
            _apimessage.StateMessage = "SystemAdmin DataGroupAction: ";
            // required
            string globalID = _apimessage.ValidateMethodParam("GlobalID");
            string groupName = _apimessage.ValidateMethodParam("GroupName");
            string encryptFlag = _apimessage.ValidateMethodParam("EncryptFlag");
            // optional
            string description = _apimessage.ValidateMethodParam("Description");

            if (globalID != "" && groupName != "" && encryptFlag != "")
            {
                DataGroupDA groupda = new DataGroupDA(_apimessage);
                groupda.DataGroupAction(actionType, globalID, groupName, description);
            }
            else
            {
                throw new Exception("Missing required input parameter(s)");
            }
        }
    }
}